//package com.saas.tenant.tenantConfig;
//
//import com.baomidou.mybatisplus.core.toolkit.StringUtils;
//import net.sf.jsqlparser.expression.Expression;
//import net.sf.jsqlparser.expression.StringValue;
//import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
//import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
//import net.sf.jsqlparser.parser.CCJSqlParserUtil;
//import net.sf.jsqlparser.schema.Column;
//import net.sf.jsqlparser.statement.Statement;
//import net.sf.jsqlparser.statement.select.PlainSelect;
//import net.sf.jsqlparser.statement.select.Select;
//import net.sf.jsqlparser.statement.select.SelectBody;
//import org.apache.ibatis.builder.StaticSqlSource;
//import org.apache.ibatis.executor.Executor;
//import org.apache.ibatis.mapping.BoundSql;
//import org.apache.ibatis.mapping.MappedStatement;
//import org.apache.ibatis.mapping.ParameterMapping;
//import org.apache.ibatis.mapping.SqlSource;
//import org.apache.ibatis.plugin.Interceptor;
//import org.apache.ibatis.plugin.Intercepts;
//import org.apache.ibatis.plugin.Invocation;
//import org.apache.ibatis.plugin.Signature;
//import org.apache.ibatis.reflection.MetaObject;
//import org.apache.ibatis.reflection.SystemMetaObject;
//import org.apache.ibatis.session.ResultHandler;
//import org.apache.ibatis.session.RowBounds;
//import org.springframework.stereotype.Component;
//
//import java.util.List;
//
///**
// * @auther Jiang Tian
// * @date 2025/3/3
// * @apiNote
// **/
//@Intercepts({
//        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
//        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
//                RowBounds.class, ResultHandler.class})
//})
//@Component
//public class TenantInterceptor implements Interceptor {
//
//    private static final String TENANT_ID_COLUMN = "tenant_id";
//
//    @Override
//    public Object intercept(Invocation invocation) throws Throwable {
//        Object[] args = invocation.getArgs();
//        MappedStatement ms = (MappedStatement) args[0];
//        Object parameter = args[1];
//
//        //获取当前租户ID
//        String tenantId = TenantContextHolder.getTenantId();
//
//        if (StringUtils.isBlank(tenantId)) {
//            return invocation.proceed();
//        }
//
//        //修改SQL
//        BoundSql boundSql = ms.getBoundSql(parameter);
//        String originalSql = boundSql.getSql();
//        SqlSource sqlSource = ms.getSqlSource();
//
//        //使用JSqlParser解析SQL
//        Statement statement = CCJSqlParserUtil.parse(originalSql);
//        if (statement instanceof Select) {
//            processSelect((Select) statement, tenantId);
//        }
//
//        //重建SQL
//        String modifiedSql = statement.toString();
//        SqlSource newSqlSource = createNewSqlSource(ms, modifiedSql);
//        MetaObject metaObject = SystemMetaObject.forObject(ms);
//        metaObject.setValue("sqlSource", newSqlSource);
//
//        return invocation.proceed();
//    }
//
//    private SqlSource createNewSqlSource(MappedStatement mappedStatement, String modifiedSql) {
//        // 1. 获取原始 SqlSource 的参数映射信息
//        BoundSql originalBoundSql = mappedStatement.getBoundSql(null);
//        List<ParameterMapping> parameterMappings = originalBoundSql.getParameterMappings();
//
//        // 2. 处理新增的租户ID参数（例如INSERT操作）
//        // 如果SQL中包含新的 tenant_id 参数，需要添加到参数映射中
//        if (modifiedSql.contains(TENANT_ID_COLUMN)) {
//            ParameterMapping tenantParamMapping = new ParameterMapping.Builder(
//                    mappedStatement.getConfiguration(),
//                    "tenantId",  // 参数名称（对应参数对象中的字段名）
//                    String.class  // 参数类型
//            ).build();
//            parameterMappings.add(tenantParamMapping);
//        }
//
//        // 3. 创建新的 SqlSource（使用 StaticSqlSource）
//        return new StaticSqlSource(
//                mappedStatement.getConfiguration(),
//                modifiedSql,
//                parameterMappings
//        );
//    }
//
//    private void processSelect(Select select, String tenantId) {
//        SelectBody selectBody = select.getSelectBody();
//        if (selectBody instanceof PlainSelect) {
//            addWhereCondition((PlainSelect) selectBody, tenantId);
//        }
//    }
//
//    private void addWhereCondition(PlainSelect plainSelect, String tenantId) {
//        Expression existingWhere = plainSelect.getWhere();
//        Expression tenantCondition = new EqualsTo(
//                new Column(TENANT_ID_COLUMN),
//                new StringValue(tenantId)
//        );
//        if (existingWhere == null) {
//            plainSelect.setWhere(tenantCondition);
//        } else {
//            AndExpression andExpression = new AndExpression(existingWhere, tenantCondition);
//            plainSelect.setWhere(andExpression);
//        }
//    }
//}
